package com.ruoyi.yys.util.excel;


import cn.afterturn.easypoi.cache.ExcelCache;
import cn.afterturn.easypoi.cache.manager.POICacheManager;
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.TemplateExportParams;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.Dict;
import cn.hutool.db.Entity;
import cn.hutool.json.JSONUtil;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.yys.common.enums.ErrorStatus;
import com.ruoyi.yys.domain.entityBo.ImportExportParamBo;
import com.ruoyi.yys.domain.export.MergeVo;
import com.ruoyi.yys.util.OssUtils;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.BufferedInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.*;

/**
 * 注释
 *
 * @author lys
 * @date 2022/11/29
 */
public class TemplateUtils {
    private static final Logger LOGGER = LoggerFactory.getLogger(ExcelCache.class);

    /**
     * 通过模板  生成文件
     *
     * @param templateExportParams 模板
     * @param data                 地图
     * @return {@link String} 生成的文件路径
     * @throws Exception 异常
     */
    public static String generateFileByTemplate(TemplateExportParams templateExportParams, Map<String, Object> data, String bdFilePath) {
        //数据写入到模板中
        Workbook workbook = ExcelExportUtil.exportExcel(templateExportParams, data);
        //创建文件夹
        FileUtil.mkParentDirs(bdFilePath);
        try {
            FileOutputStream fos = new FileOutputStream(bdFilePath);
            workbook.write(fos);
            fos.close();
        } catch (Exception e) {
            throw new ServiceException(ErrorStatus.EXCEPTION.getCode(), "模板导出失败" + e.getMessage());
        }
        return bdFilePath;
    }

    /**
     * 通过模板  生成文件
     *
     * @param ossPath oss路径
     * @param data    数据
     * @return {@link String} 生成的文件路径
     * @throws Exception 异常
     */
    public static String generateFileByTemplateOssPath(String ossPath, Map<String, Object> data, String bdFilePath) throws Exception {
        TemplateExportParams templateByOssPath = getTemplateByOssPath(ossPath);
        return generateFileByTemplate(templateByOssPath, data, bdFilePath);
    }

    /**
     * 通过模板  生成文件
     *
     * @param filePath 本地文件路径
     * @param datas    数据
     * @return {@link String} 生成的文件路径
     * @throws Exception 异常
     */
    public static String generateFileByTemplateOssPath(String filePath, List<Entity> datas, String bdFilePath) {
        TemplateExportParams templateByOssPath = getTemplateByOssPath(filePath);
        try {
            return generateFileByTemplate(templateByOssPath, Dict.create().set("datas", datas), bdFilePath);
        } catch (Exception e) {
            throw new ServiceException(400, "oss模板导出失败：" + e.getMessage());
        }
    }

    /**
     * 通过模板  生成文件
     *
     * @param filePath 本地文件路径
     * @param data     数据
     * @return {@link String} 生成的文件路径
     * @throws Exception 异常
     */
    public static String generateFileByTemplateFliePath(String filePath, Map<String, Object> data, String bdFilePath) throws Exception {
        TemplateExportParams templateByOssPath = getTemplateByFliePath(filePath);
        return generateFileByTemplate(templateByOssPath, data, bdFilePath);
    }

    /**
     * 通过模板  生成文件
     *
     * @param filePath 本地文件路径
     * @param datas    数据
     * @return {@link String} 生成的文件路径
     * @throws Exception 异常
     */
    public static String generateFileByTemplateFliePath(String filePath, List<Entity> datas, String bdFilePath) {
        TemplateExportParams templateByOssPath = getTemplateByFliePath(filePath);
        try {
            return generateFileByTemplate(templateByOssPath, Dict.create().set("datas", datas), bdFilePath);
        } catch (Exception e) {
            throw new ServiceException(ErrorStatus.EXCEPTION.getCode(), "本地模板导出失败：" + e.getMessage());
        }
    }

    /**
     * 通过模板  生成文件
     *
     * @param is   模板文件流
     * @param data 数据
     * @return {@link String} 生成的文件路径
     * @throws Exception 异常
     */
    public static String generateFileByTemplateInputStream(InputStream is, Map<String, Object> data, String bdFilePath) throws Exception {
        TemplateExportParams templateByOssPath = getTemplateByInputStream(is);
        return generateFileByTemplate(templateByOssPath, data, bdFilePath);
    }

    /**
     * 通过模板  生成文件
     *
     * @param is    文件流
     * @param datas 数据
     * @return {@link String} 生成的文件路径
     * @throws Exception 异常
     */
    public static String generateFileByTemplateOssPath(InputStream is, List<Entity> datas, String bdFilePath) throws Exception {
        TemplateExportParams templateByOssPath = getTemplateByInputStream(is);
        return generateFileByTemplate(templateByOssPath, Dict.create().set("datas", datas), bdFilePath);
    }

    /**
     * 通过本地文件路径获取模板
     *
     * @param fliePath 本地文件路径
     * @return {@link TemplateExportParams}
     */
    public static TemplateExportParams getTemplateByFliePath(String fliePath) {
        TemplateExportParams templateExportParams = new TemplateExportParams(fliePath);
        return templateExportParams;
    }

    /**
     * 通过oss路径获取模板
     *
     * @param ossPath oss路径
     * @return {@link TemplateExportParams}
     */
    public static TemplateExportParams getTemplateByOssPath(String ossPath) {
        TemplateExportParams templateExportParams = new TemplateExportParams();
        //获取workbook
        Workbook wb = getWorkbook(OssUtils.getFileStream(ossPath));
        templateExportParams.setTemplateWb(wb);
        return templateExportParams;
    }

    /**
     * 通过inputStream获取模板
     *
     * @param is 是
     * @return {@link TemplateExportParams}
     */
    public static TemplateExportParams getTemplateByInputStream(InputStream is) {
        TemplateExportParams templateExportParams = new TemplateExportParams();
        //获取workbook
        Workbook wb = getWorkbook(is);
        templateExportParams.setTemplateWb(wb);
        return templateExportParams;
    }

    public static Workbook getWorkbook(String url, Integer[] sheetNums, boolean needAll) {
        InputStream is = null;
        List<Integer> sheetList = Arrays.asList(sheetNums);
        try {
            is = POICacheManager.getFile(url);
            Workbook wb = WorkbookFactory.create(is);
            // 删除其他的sheet
            if (!needAll) {
                for (int i = wb.getNumberOfSheets() - 1; i >= 0; i--) {
                    if (!sheetList.contains(i)) {
                        wb.removeSheetAt(i);
                    }
                }
            }
            return wb;
        } catch (Exception e) {
            LOGGER.error(e.getMessage(), e);
        } finally {
            try {
                is.close();
            } catch (Exception e) {
                LOGGER.error(e.getMessage(), e);
            }
        }
        return null;
    }

    public static Workbook getWorkbook(InputStream is) {
        return getWorkbook(is, new Integer[]{0}, false);
    }

    public static Workbook getWorkbook(InputStream is, Integer[] sheetNums, boolean needAll) {
        List<Integer> sheetList = Arrays.asList(sheetNums);
        try {
            Workbook wb = WorkbookFactory.create(is);
            // 删除其他的sheet
            if (!needAll) {
                for (int i = wb.getNumberOfSheets() - 1; i >= 0; i--) {
                    if (!sheetList.contains(i)) {
                        wb.removeSheetAt(i);
                    }
                }
            }
            return wb;
        } catch (Exception e) {
            LOGGER.error(e.getMessage(), e);
        } finally {
            try {
                is.close();
            } catch (Exception e) {
                LOGGER.error(e.getMessage(), e);
            }
        }
        return null;
    }
}
